package features.advance.edu.compilers.chapt2;

import features.advance.edu.compilers.exception.SyntaxException;

/**
 * @author LIN
 * @date 2022-01-12 10:52
 */
public class Exercise2_4 {

    public static void main(String[] args) {
        Solution solution = new Solution() {
        };
//        solution.setStr("+++--+-+-+-+-+++-a-aaaaaaaaaaaaaaaa");
        solution.setStr("ababababab");
        try{
            solution.S4();
        }catch(Exception e){
            e.printStackTrace();
        }

    }

    static class Solution {
        String lookahead;
        String str;
        int index = 0;

        public void setStr(String str) {
            if(str != null){
                lookahead = String.valueOf(str.toCharArray()[0]);
            }
            this.str = str;

        }

        /**
         *  S -> ab S | ε
         * @throws SyntaxException
         */
        void S4() throws SyntaxException {
            if(lookahead == null) return;
            switch (lookahead){
                case "a":
                    match("a");match("b");S4();
                    break;
                default:
                    throw new SyntaxException();
            }


        }
        /**
         *  S -> + S S | - S S | a
         */
        void S1() throws Exception{
            if(lookahead == null){
                return;
            }
            switch (lookahead){
                case "+":
                    match("+");S1();S1();
                    break;
                case "-":
                    match("-");S1();S1();
                    break;
                case "a":
                    match("a");
                    break;
                default:
                    throw new Exception("语法错误");

            }
        }

        /**
         *  S -> S ( S ) S | ε
         */
        void S2() throws Exception {
            if(lookahead == null) return;

            if("(".equals(lookahead)){
                match("(");S2();match(")");S2();
            }
        }

        /**
         * S -> 0 S 1 | 0 1
         */
        void S3() throws Exception {
            if(lookahead == null) return;

            switch (lookahead){
                case "0":
                    match("0");S3();match("1");
                    break;
                case "1":
                    break;
                default:
                    throw new Exception("语法错误");
            }
        }

        void match(String t) throws SyntaxException {
            if(lookahead.equals(t)){
                lookahead = nextTerminal();
            }else{
                throw new SyntaxException("语法错误");
            }
        }
        String nextTerminal(){
            if(str != null){
                return ++index>=str.length()?null:String.valueOf(str.toCharArray()[index]);
            }
            return null;
        }


    }
}
